package com.neusoft.hifly.core.log;

import java.io.PrintWriter;
import java.io.StringWriter;

import org.apache.commons.lang3.StringUtils;

import com.neusoft.hifly.commons.lang.StringUtil;

/**
 * Title: 核心类库
 * <p>
 * Description: 使用slf4j日志模块封装的日志组件
 * <p>
 * 使用前，必须先注入logPath参数
 * <p>
 * 对应的四个日志文件：debug.log/info.log/warn.log/error.log
 * <p>
 * Copyright: Copyright (c) 2010 - 2011
 * <p>
 * Company: 东软汉枫
 *
 * @author lh_neu
 * @version 1.0.0
 */
public class Log {

	private static final org.slf4j.Logger Logger = org.slf4j.LoggerFactory.getLogger(Log.class);

	/**
	 * 是否显示运行时间
	 */
	private static boolean isShowTime;

	/**
	 * 是否Info级别
	 */
	public static boolean isInfoEnabled() {
		return Log.Logger.isInfoEnabled();
	}

	/**
	 * 是否Debug级别
	 */
	public static boolean isDebugEnabled() {
		return Log.Logger.isDebugEnabled();
	}

	/**
	 * 是否Warn级别
	 */
	public static boolean isWarnEnabled() {
		return Log.Logger.isWarnEnabled();
	}

	/**
	 * 是否Error级别
	 */
	public static boolean isErrorEnabled() {
		return Log.Logger.isErrorEnabled();
	}

	/**
	 * 写入Info日志
	 *
	 * @param s
	 *            日志
	 */
	public static void info(final String s) {
		if (StringUtils.isNotEmpty(s) && Log.isInfoEnabled() && Log.isShowTime(s)) {
			Log.Logger.info(s);
		}
	}

	/**
	 * 写入Info日志
	 *
	 * @param throwable
	 *            异常
	 */
	public static void info(final Throwable throwable) {
		if (throwable != null) {
			if (Log.isInfoEnabled()) {
				Log.Logger.info("", throwable);
			}
			throwable.printStackTrace();
		}
	}

	/**
	 * 写入Info日志
	 *
	 * @param s
	 *            日志
	 * @param throwable
	 *            异常
	 */
	public static void info(final String s, final Throwable throwable) {
		if (throwable != null) {
			throwable.printStackTrace();
		}
		if (Log.isInfoEnabled()) {
			Log.Logger.info(s, throwable);
		}
	}

	/**
	 * 写入Info日志
	 * <p>
	 * 可以使用{}配置参数。例如："用户 {} 登录时间 {} !", new Object[] { "lihui", "20110101" }
	 *
	 * @param s
	 *            日志
	 * @param args
	 *            参数
	 */
	public static void info(final String s, final Object[] args) {
		if (Log.isInfoEnabled()) {
			Log.Logger.info(s, args);
		}
	}

	/**
	 * 写入Debug日志
	 *
	 * @param s
	 *            日志
	 */
	public static void debug(final String s) {
		if (StringUtils.isNotEmpty(s) && Log.isDebugEnabled() && Log.isShowTime(s)) {
			Log.Logger.debug(s);
		}
	}

	/**
	 * 写入Debug日志
	 *
	 * @param throwable
	 *            异常
	 */
	public static void debug(final Throwable throwable) {
		if (throwable != null) {
			if (Log.isDebugEnabled()) {
				Log.Logger.debug("", throwable);
			}
			throwable.printStackTrace();
		}
	}

	/**
	 * 写入Debug日志
	 *
	 * @param s
	 *            日志
	 * @param throwable
	 *            异常
	 */
	public static void debug(final String s, final Throwable throwable) {
		if (Log.isDebugEnabled()) {
			Log.Logger.debug(s, throwable);
		}
	}

	/**
	 * 写入Debug日志
	 * <p>
	 * 可以使用{}配置参数。例如："用户 {} 登录时间 {} !", new Object[] { "lihui", "20110101" }
	 *
	 * @param s
	 *            日志
	 * @param args
	 *            参数
	 */
	public static void debug(final String s, final Object[] args) {
		if (Log.isDebugEnabled()) {
			Log.Logger.debug(s, args);
		}
	}

	/**
	 * 写入Warn日志
	 *
	 * @param s
	 *            日志
	 */
	public static void warn(final String s) {
		if (StringUtils.isNotEmpty(s) && Log.isWarnEnabled() && Log.isShowTime(s)) {
			Log.Logger.warn(s);
		}
	}

	/**
	 * 写入Warn日志
	 *
	 * @param throwable
	 *            异常
	 */
	public static void warn(final Throwable throwable) {
		if (throwable != null) {
			if (Log.isWarnEnabled()) {
				Log.Logger.warn("", throwable);
			}
			throwable.printStackTrace();
		}
	}

	/**
	 * 写入Warn日志
	 *
	 * @param s
	 *            日志
	 * @param throwable
	 *            异常
	 */
	public static void warn(final String s, final Throwable throwable) {
		if (Log.isWarnEnabled()) {
			Log.Logger.warn(s, throwable);
		}
	}

	/**
	 * 写入Warn日志
	 * <p>
	 * 可以使用{}配置参数。例如："用户 {} 登录时间 {} !", new Object[] { "lihui", "20110101" }
	 *
	 * @param s
	 *            日志
	 * @param args
	 *            参数
	 */
	public static void warn(final String s, final Object[] args) {
		if (Log.isWarnEnabled()) {
			Log.Logger.warn(s, args);
		}
	}

	/**
	 * 写入Error日志
	 *
	 * @param s
	 *            日志
	 */
	public static void error(final String s) {
		if (StringUtils.isNotEmpty(s) && Log.isErrorEnabled() && Log.isShowTime(s)) {
			Log.Logger.error(s);
			if (Log.isDebugEnabled()) {
				Log.printToStdErr(s, null);
			}
		}
	}

	/**
	 * 写入Error日志
	 *
	 * @param throwable
	 *            异常
	 */
	public static void error(final Throwable throwable) {
		if (throwable != null) {
			if (Log.isErrorEnabled()) {
				Log.Logger.error("", throwable);
				if (Log.isDebugEnabled()) {
					Log.printToStdErr(null, throwable);
				}
			}
		}
	}

	/**
	 * 写入Error日志
	 *
	 * @param s
	 *            日志
	 * @param throwable
	 *            异常
	 */
	public static void error(final String s, final Throwable throwable) {
		if (Log.isErrorEnabled()) {
			Log.Logger.error(s, throwable);
			if (Log.isDebugEnabled()) {
				Log.printToStdErr(s, throwable);
			}
		}
	}

	/**
	 * 写入Error日志
	 * <p>
	 * 可以使用{}配置参数。例如："用户 {} 登录时间 {} !", new Object[] { "lihui", "20110101" }
	 *
	 * @param s
	 *            日志
	 * @param args
	 *            参数
	 */
	public static void error(final String s, final Object[] args) {
		if (Log.isErrorEnabled()) {
			Log.Logger.error(s, args);
			if (Log.isDebugEnabled()) {
				Log.printToStdErr(s + "  " + StringUtil.arr2Str(args), null);
			}
		}
	}

	/**
	 * 输出错误日志
	 *
	 * @param s
	 *            信息
	 * @param throwable
	 *            异常
	 */
	private static void printToStdErr(final String s, final Throwable throwable) {
		if (s != null) {
			System.err.println(s);
		}
		if (throwable != null) {
			final StringWriter sw = new StringWriter();
			final PrintWriter pw = new PrintWriter(sw);
			throwable.printStackTrace(pw);
			System.err.print(sw.toString());
			System.err.print("\n");
		}
	}

	/**
	 * 是否显示运行时间
	 *
	 * @param s
	 *            日志
	 * @return 是否显示
	 */
	public static boolean isShowTime(final String s) {
		if (StringUtils.isEmpty(s)) {
			return false;
		}
		if (!Log.isShowTime && StringUtils.indexOf(s, "花费时间 ") >= 0) {
			return false;
		}
		return true;
	}

	public void setIsShowTime(final boolean isShowTime) {
		Log.isShowTime = isShowTime;
	}

	/**
	 * 测试
	 *
	 * @param args
	 *            参数
	 */
	public static void main(final String[] args) {
		Log.error("用户  {} 登录时间 {} !", new Object[] { "lihui", "20110101" });
		Log.error("系统错误。<{}> {}.", new Object[] { "001", "登录失败" });
	}

}